package utils;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
import java.util.Vector;
import java.util.function.BiConsumer;

import FCRendering.FCRMaster;
import Function.FCMapAnimationLibrary;
import Function.FCMutilPlayCache;
import Function.FCTankLibrary;
import Function.Utils.CacheFileUtil;
import VWorldGameStudio.*;
import com.google.gson.Gson;
import utils.entity.BigSavePack;

/**
 * 数据（文件）的写操作在这里完成<br>
 * 查看读取操作类，删除操作类请跳转以下链接：<br>
 *
 * @author jungle
 * @see utils.FCDataRead
 * @see utils.FCDataDelete
 */
public class FCDataWrite implements FCDataWriteable {

    /**
     * 写入数据
     */
    private BufferedWriter writer;
    private Gson gson = new Gson();

    protected FCDataWrite() {
    }

    /**
     * 写入存档
     */
    @Override
    public boolean writeSaveData(FCPlayerInfo player1,
                                 FCSave gamesave, FCDate gamedate, FCTankLibrary tankl) {
        FCDataSingles.getReader();
        try {
            File f = new File(
                    FCFileUrl.URL_DATA_SAVE
                            + FCDataSingles.getFileNameDE().filenameEncryption(gamesave.HOST_UID + "-" + player1.getName()) + ".vw");
            if (!f.exists())
                f.createNewFile();
            BigSavePack bigSavePack = new BigSavePack();
            bigSavePack.player1 = player1;
            FCTank tank = tankl.getTankOfID(player1.getPlayertank1(), gamesave.HOST_UID);
            if (tank != null) {
                tank.setPdir(player1.getActionDir());
                tank.setPPianYiX(player1.getPianYiX());
                tank.setPPianYiY(player1.getPianYiY());
                tank.setPcoorX(player1.getPlayer1CoorX());
                tank.setPcoorY(player1.getPlayer1CoorY());
                tank.setPmapname(player1.getMapname());
                tank.setPactionNum(player1.getActionNum());
            }
            for (FCRPlayerLink fcrPlayerLink : FCMutilPlayCache.getTeamMembers()) {
                if (fcrPlayerLink.curPlayerHostUID.equals(gamesave.HOST_UID)) {
                    FCPlayerInfo p = FCMutilPlayCache.findPlayerByName(fcrPlayerLink.curPlayerHostUID, fcrPlayerLink.curPlayerName);
                    if (p == null) continue;
                    FCTank find = tankl.getTankOfID(p.getPlayertank1(), gamesave.HOST_UID);
                    if (find != null) {
                        find.setPdir(p.getActionDir());
                        find.setPPianYiX(p.getPianYiX());
                        find.setPPianYiY(p.getPianYiY());
                        find.setPcoorX(p.getPlayer1CoorX());
                        find.setPcoorY(p.getPlayer1CoorY());
                        find.setPmapname(p.getMapname());
                        find.setPactionNum(p.getActionNum());
                    }
                }
            }
            gamesave.getSaveFCPropulsionStrings().clear();
            for (FCPropulsion fc : FCRMaster.fcv.getLocalPropulsions()) {
                gamesave.getSaveFCPropulsionStrings().add(fc.getSaveString());
            }
            //--------------------------------------删除其他玩家坦克的物品
            ArrayList<String> hasItems = new ArrayList<>();
            gamesave.saveAllTankItem.forEach(new BiConsumer<String, FCItem>() {
                @Override
                public void accept(String s, FCItem item) {
                    hasItems.add(s);
                }
            });
            gamesave.getTankSaveIos().forEach(new BiConsumer<String, FCTank>() {
                @Override
                public void accept(String s, FCTank tank) {
                    gamesave.removeLocalItems(hasItems, tank);
                }
            });
            for(String itemN: gamesave.getFcBankList()){
                hasItems.remove(itemN);
            }
            for(String leftSt: hasItems){
                gamesave.saveAllTankItem.remove(leftSt);
                System.out.println("多余的道具："+leftSt);
            }
            //-------------------------------------------
            bigSavePack.gameSave = gamesave;
            bigSavePack.gameDate = gamedate;
            ArrayList<FCPlayerInfo> teams = new ArrayList<>(0);//队伍保存
            for (FCRPlayerLink fcrPlayerLink : FCMutilPlayCache.getTeamMembers()) {
                if (fcrPlayerLink.curPlayerHostUID.equals(gamesave.HOST_UID)) {
                    teams.add(FCMutilPlayCache.findPlayerByName(gamesave.HOST_UID, fcrPlayerLink.curPlayerName));
                }
            }
            bigSavePack.teams = teams;
            //System.out.println("write: " + gson.toJson(bigSavePack));
            String compressS = FCMixUtil.compress(gson.toJson(bigSavePack));
            System.out.println("compressS: " + compressS);
            CacheFileUtil.getInstance().saveCacheInfo(f.getAbsolutePath(), compressS);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 写入剧情数据
     */
    @Override
    public void writePlotData(FCPlot pl) {
        try {
            File f = new File(FCFileUrl.URL_DATA_PLOT + pl.getId() + ".vw");
            if (!f.exists())
                f.createNewFile();
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), "UTF-8"));
            writer.write((FCDataSingles.getDataDE().dataEncryption("id=" + pl.getId()) + "\r\n"));
            writer.write(
                    (FCDataSingles.getDataDE().dataEncryption("touchoff=" + pl.getTouchoff()) + "\r\n"));
            writer.write(
                    (FCDataSingles.getDataDE().dataEncryption("active=" + pl.getActive().size()) + "\r\n"));
            Vector<String> da = pl.getActive();
            for (int i = 0; i < da.size(); i++)
                writer.write((FCDataSingles.getDataDE().dataEncryption("active[" + i + "]=" + da.get(i)) + "\r\n")
                );
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * TODO 写入攻击动画
     */
    @Override
    public void writeAnimationData(FCAnimation ani) {
        try {
            File f = new File(FCFileUrl.URL_DATA_ANIMATION + ani.getID() + ".vw");
            if (!f.exists())
                f.createNewFile();
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), "UTF-8"));
            writer.write((FCDataSingles.getDataDE().dataEncryption("id=" + ani.getID()) + "\r\n"));
            writer.write((FCDataSingles.getDataDE().dataEncryption("type=" + ani.getType()) + "\r\n"));
            writer.write((FCDataSingles.getDataDE().dataEncryption("forwho=" + ani.getAnimationForWho()) + "\r\n"));
            writer.write(
                    (FCDataSingles.getDataDE().dataEncryption("fire=" + ani.getFireAniForWrite()) + "\r\n"));
            writer.write((FCDataSingles.getDataDE().dataEncryption("fly=" + ani.getFlyAniForWrite()) + "\r\n")
            );
            writer.write((FCDataSingles.getDataDE().dataEncryption("fly2=" + ani.getFlyAniForWrite2()) + "\r\n")
            );
            writer.write((FCDataSingles.getDataDE().dataEncryption("boom=" + ani.getBoomAniForWrite()) + "\r\n")
            );
            writer.write((FCDataSingles.getDataDE().dataEncryption("boomScale=" + ani.getBoomPngScales()) + "\r\n")
            );
            writer.close();
            System.out.println("FCAnimation " + ani.getID() + " " + ani.getFireAniForWrite() + " " + ani.getFlyAniForWrite() + " " +
                    ani.getFlyAniForWrite2() + " " + ani.getBoomAniForWrite() + " 放大倍数：" + ani.getBoomPngScales());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 写入动作
     */
    @Override
    public void writeActionData(FCAction act) {
        try {
            File f = new File(FCFileUrl.URL_DATA_ACTION + act.getName() + ".vw");
            if (!f.exists())
                f.createNewFile();
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), "UTF-8"));
            writer.write((FCDataSingles.getDataDE().dataEncryption("name=" + act.getName()) + "\r\n"));
            writer.write((FCDataSingles.getDataDE().dataEncryption("type=" + act.getType()) + "\r\n"));
            writer.write((FCDataSingles.getDataDE().dataEncryption("face=" + act.getFace()) + "\r\n"));
            writer.write((FCDataSingles.getDataDE().dataEncryption("fixedroute=" + gson.toJson(act.getFixedRoute())) + "\r\n"));
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 写入事件
     */
    @Override
    public void writeEventData(FCEvent ent) {
        try {
            File f = new File(FCFileUrl.URL_DATA_EVENT + ent.getName() + ".vw");
            if (!f.exists())
                f.createNewFile();
            CacheFileUtil.getInstance().saveCacheInfo(f.getAbsolutePath(), gson.toJson(ent));
            System.out.println("write："+gson.toJson(ent));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 写入地图
     */
    @Override
    public void writeMapData(FCMap map) {
        try {
            File f = new File(FCFileUrl.URL_DATA_MAP + map.getName() + ".vw");
            if (!f.exists())
                f.createNewFile();
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), "UTF-8"));
            writer.write((FCDataSingles.getDataDE().dataEncryption("name=" + map.getName()) + "\r\n"));
            writer.write((FCDataSingles.getDataDE().dataEncryption("info=" + map.getInfo()) + "\r\n"));
            writer.write(
                    (FCDataSingles.getDataDE().dataEncryption("size=" + map.getMapWidth() + "/" + map.getMapHeight())
                            + "\r\n"));
            writer.write((FCDataSingles.getDataDE().dataEncryption("background=" + map.getBackgroundURL()) + "\r\n")
            );
            // 写入unplace
            String qw[][] = map.getLowerPlace();
            writer.write((FCDataSingles.getDataDE().dataEncryption("unplace=" + qw.length) + "\r\n"));
            for (int i = 0; i < qw.length; i++) {
                String qq = "unplace[" + i + "]=";
                for (int j = 0; j < qw[i].length; j++)
                    qq += qw[i][j] + "/";
                writer.write((FCDataSingles.getDataDE().dataEncryption(qq) + "\r\n"));
            }
            // 写入place
            String as[][] = map.getUpperPlace();
            writer.write((FCDataSingles.getDataDE().dataEncryption("place=" + as.length) + "\r\n"));
            for (int i = 0; i < as.length; i++) {
                String qq = "place[" + i + "]=";
                for (int j = 0; j < as[i].length; j++)
                    qq += as[i][j] + "/";
                writer.write((FCDataSingles.getDataDE().dataEncryption(qq) + "\r\n"));
            }
            // 写入eventname
            String zx[][] = map.getEventName();
            writer.write((FCDataSingles.getDataDE().dataEncryption("eventname=" + zx.length) + "\r\n"));
            for (int i = 0; i < zx.length; i++) {
                String qq = "eventname[" + i + "]=";
                for (int j = 0; j < zx[i].length; j++)
                    qq += zx[i][j] + "/";
                writer.write((FCDataSingles.getDataDE().dataEncryption(qq) + "\r\n"));
            }
            // 写入entity1
            int we[][] = map.getCollisionLevelLowerPlace();
            writer.write((FCDataSingles.getDataDE().dataEncryption("entity1=" + we.length) + "\r\n"));
            for (int i = 0; i < we.length; i++) {
                String qq = "entity1[" + i + "]=";
                for (int j = 0; j < we[i].length; j++)
                    qq += we[i][j] + "/";
                writer.write((FCDataSingles.getDataDE().dataEncryption(qq) + "\r\n"));
            }
            // 写入entity2
            int sd[][] = map.getCollisionLevelUpperPlace();
            writer.write((FCDataSingles.getDataDE().dataEncryption("entity2=" + sd.length) + "\r\n"));
            for (int i = 0; i < sd.length; i++) {
                String qq = "entity2[" + i + "]=";
                for (int j = 0; j < sd[i].length; j++)
                    qq += sd[i][j] + "/";
                writer.write((FCDataSingles.getDataDE().dataEncryption(qq) + "\r\n"));
            }
            // 写入npc
            HashMap<String, String> mapnpc = map.getMapNpcHashMap();
            String poi = "";
            Set<String> lkj = mapnpc.keySet();
            for (String npccoor : lkj)
                poi += npccoor + "," + mapnpc.get(npccoor) + "/";
            writer.write((FCDataSingles.getDataDE().dataEncryption("mapnpc=" + poi) + "\r\n"));
            // 写入tank
            mapnpc = map.getMapTankHashMap();
            poi = "";
            lkj = mapnpc.keySet();
            for (String npccoor : lkj)
                poi += npccoor + "," + mapnpc.get(npccoor) + "/";
            writer.write((FCDataSingles.getDataDE().dataEncryption("maptank=" + poi) + "\r\n"));
            // 写入monster
            writer.write((FCDataSingles.getDataDE().dataEncryption("monsterArea=" + gson.toJson(map.getMapAndMsEntities())) + "\r\n"));
            if (map.getMapAnimation() != null) {
                writer.write((FCDataSingles.getDataDE().dataEncryption("mapAni=" + gson.toJson(map.getMapAnimation())) + "\r\n"));
            }

            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 写入怪物
     */
    @Override
    public void writeMonsterData(FCMonster mon) {
        try {
            File f = new File(FCFileUrl.URL_DATA_MONSTER + mon.getName() + ".vw");
            if (!f.exists())
                f.createNewFile();
            CacheFileUtil.getInstance().saveCacheInfo(f.getAbsolutePath(), gson.toJson(mon));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 写入物品
     */
    @Override
    public void writeItemData(FCItem it) {
        try {
            File f = new File(FCFileUrl.URL_DATA_ITEM + it.getName() + ".vw");
            if (!f.exists())
                f.createNewFile();
            CacheFileUtil.getInstance().saveCacheInfo(f.getAbsolutePath(), gson.toJson(it));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 写入坦克
     */
    @Override
    public void writeTankData(FCTank tank) {
        try {

            File f = new File(FCFileUrl.URL_DATA_TANK + tank.getName() + ".vw");
            if (!f.exists())
                f.createNewFile();
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), "UTF-8"));
            writer.write(FCDataSingles.getDataDE().dataEncryption("name=" + tank.getName()) + "\r\n");
            writer.write(FCDataSingles.getDataDE().dataEncryption("gunid=" + tank.getGunID()) + "\r\n");
            writer.write(FCDataSingles.getDataDE().dataEncryption("gun2id=" + tank.getGun2ID()) + "\r\n");
            writer.write(FCDataSingles.getDataDE().dataEncryption("engineid=" + tank.getEngineID()) + "\r\n");
            writer.write(FCDataSingles.getDataDE().dataEncryption("cdeviceid=" + tank.getCdeviceID()) + "\r\n");
            writer.write(FCDataSingles.getDataDE().dataEncryption("chassisid=" + tank.getChassisID()) + "\r\n");
            writer.write(FCDataSingles.getDataDE().dataEncryption("radarid=" + tank.getRadarID()) + "\r\n");
            writer.write(FCDataSingles.getDataDE().dataEncryption("masterpngurl=" + tank.getImageMasterUrl()) + "\r\n");
            writer.write(FCDataSingles.getDataDE().dataEncryption("dirpngurl=" + tank.getImageDirUrl()) + "\r\n");
            writer.write(FCDataSingles.getDataDE().dataEncryption("whitelinepngurl=" + tank.getImageWhiteLineUrl()) + "\r\n");
            writer.write(FCDataSingles.getDataDE().dataEncryption("SEid=" + tank.getSEID()));
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 写入人物
     */
    @Override
    public void writeCharacterData(FCCharacter cha) {
        try {
            File f = new File(FCFileUrl.URL_DATA_CHARACTER + cha.getCharacterName() + ".vw");
            if (!f.exists())
                f.createNewFile();
            System.out.println("write--> Name:"+ cha.getCharacterName()+",type:"+cha.getCharacterType()+",action:"+cha.getCharacterActionID()
            +",png:"+cha.getCharacterPngurl()+" eventId:"+cha.getCharacterEventID());
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), "UTF-8"));
            writer.write(
                    (FCDataSingles.getDataDE().dataEncryption("name=" + cha.getCharacterName()) + "\r\n"));
            writer.write(
                    (FCDataSingles.getDataDE().dataEncryption("type=" + cha.getCharacterType()) + "\r\n"));
            writer.write((FCDataSingles.getDataDE().dataEncryption("actionid=" + cha.getCharacterActionID()) + "\r\n")
            );
            writer.write((FCDataSingles.getDataDE().dataEncryption("eventid=" + cha.getCharacterEventID()) + "\r\n")
            );
            writer.write(FCDataSingles.getDataDE().dataEncryption("pngurl=" + cha.getCharacterPngurl()));
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 写入方块
     */
    @Override
    public void writeBlockData(FCBlock block) {
        try {
            File f = new File(FCFileUrl.URL_DATA_BLOCK + block.getBlockID() + ".vw");
            if (!f.exists())
                f.createNewFile();
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), "UTF-8"));
            writer.write(
                    (FCDataSingles.getDataDE().dataEncryption("name=" + block.getBlockID()) + "\r\n"));
            writer.write(
                    (FCDataSingles.getDataDE().dataEncryption("type=" + block.getBlockType()) + "\r\n"));
            writer.write(
                    (FCDataSingles.getDataDE().dataEncryption("eventid=" + block.getEventID()) + "\r\n"));
            String[] pngurl = block.getBlockPngUrl();
            writer.write(FCDataSingles.getDataDE().dataEncryption("pngurl="));
            for (int i = 0; i < pngurl.length; i++)
                writer.write(FCDataSingles.getDataDE().dataEncryption(pngurl[i] + "//"));
            writer.write(("\r\n" + FCDataSingles.getDataDE().dataEncryption("model=")));
            int[][] model = block.getBlockModel();
            for (int i = 0; i < model.length; i++) {
                for (int j = 0; j < model[i].length; j++) {
                    writer.write(FCDataSingles.getDataDE()
                            .dataEncryption(String.valueOf((model[i][j] == 0) ? "zero" : model[i][j]) + "v")
                    );
                }
                writer.write(FCDataSingles.getDataDE().dataEncryption("/"));
            }
            writer.write(("\r\n" + FCDataSingles.getDataDE().dataEncryption("coor=")));
            int[][] coor = block.getBlockCoor();
            for (int i = 0; i < coor.length; i++) {
                for (int j = 0; j < coor[i].length; j++) {
                    writer.write(FCDataSingles.getDataDE().dataEncryption(String.valueOf(coor[i][j]) + "v"));
                }
                writer.write(FCDataSingles.getDataDE().dataEncryption("/"));
            }
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void writeMapAnimationData(FCMapAnimation mon) {
        try {
            File f = new File(FCMapAnimationLibrary.DIR_PATH + mon.getAName() + ".vw");
            if (!f.exists())
                f.createNewFile();
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), "UTF-8"));
            writer.write((FCDataSingles.getDataDE().dataEncryption("name=" + mon.getAName()) + "\r\n"));
            writer.write((FCDataSingles.getDataDE().dataEncryption("level=" + mon.getMapLevel()) + "\r\n"));
            writer.write((FCDataSingles.getDataDE().dataEncryption("imgW=" + mon.getImgSizeW()) + "\r\n"));
            writer.write((FCDataSingles.getDataDE().dataEncryption("imgH=" + mon.getImgSizeH()) + "\r\n"));
            writer.write((FCDataSingles.getDataDE().dataEncryption("visiable=" + mon.getVisiable()) + "\r\n"));
            writer.write((FCDataSingles.getDataDE().dataEncryption("playTimes=" + mon.getNeedPlayTime()) + "\r\n"));

            writer.write((FCDataSingles.getDataDE().dataEncryption("imgUrl=" + gson.toJson(mon.getAnimatImgUrls())) + "\r\n"));
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
